package com.example.service;

import ch.qos.logback.classic.Logger;
import com.example.data.entity.QuestionInfo;
import com.example.data.vo.Triple;
import com.example.util.LlmClientUtil;
import jakarta.annotation.Resource;
import org.apache.logging.log4j.util.PropertySource;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;

/**
 * 答案生成器，用于将三元组查询结果转换为自然语言回答
 */
@Component
public class AnswerGenerator {

    @Resource
    private LlmClientUtil llmClientUtil;

    /**
     * 根据查询结果生成自然语言回答
     */
    public String generateAnswer(QuestionInfo questionInfo, List<Triple> triples) {
        if (triples == null || triples.isEmpty()) {
            return generateNoAnswer(questionInfo);
        }

        // 新增：无关系时的答案生成（兜底）
        if (questionInfo.getRelationType() == null) {
            return generateNoRelationAnswer(questionInfo, triples);
        }

        // 根据问题类型生成不同的回答
        if ("描述".equals(questionInfo.getRelationType())) {
            return generateDescriptionAnswer(triples);
        } else if ("属于".equals(questionInfo.getRelationType())) {
            return generateTypeAnswer(triples);
        } else if (questionInfo.isAskingForHeadEntity()) {
            return generateHeadEntityAnswer(questionInfo, triples);
        } else {
            return generateTailEntityAnswer(questionInfo, triples);
        }
    }

    /**
     * 生成实体描述的回答
     */
    private String generateDescriptionAnswer(List<Triple> triples) {
        // 取第一个相关实体的描述
        Triple triple = triples.get(0);
        String entityName = triple.getHeadEntityName() != null ?
                triple.getHeadEntityName() : triple.getTailEntityName();
        String desc = triple.getHeadEntityDesc() != null ?
                triple.getHeadEntityDesc() : triple.getTailEntityDesc();

        if (desc != null && !desc.isEmpty()) {
            return entityName + "是" + desc + "。";
        } else {
            return "关于" + entityName + "的详细描述信息暂未找到。";
        }
    }

    /**
     * 生成实体类型的回答
     */
    private String generateTypeAnswer(List<Triple> triples) {
        Triple triple = triples.get(0);
        String entityName = triple.getHeadEntityName() != null ?
                triple.getHeadEntityName() : triple.getTailEntityName();
        String type = triple.getHeadEntityType() != null ?
                triple.getHeadEntityType() : triple.getTailEntityType();

        return entityName + "属于" + type + "类型。";
    }

    /**
     * 生成询问头实体的回答（如"谁建立了秦朝？"）
     */
    private String generateHeadEntityAnswer(QuestionInfo questionInfo, List<Triple> triples) {
        StringBuilder answer = new StringBuilder();

        if (triples.size() == 1) {
            Triple triple = triples.get(0);
            answer.append(triple.getHeadEntityName())
                    .append(triple.getRelationType())
                    .append("了")
                    .append(questionInfo.getKnownTailEntity())
                    .append("。");
        } else {
            answer.append("以下实体").append(questionInfo.getRelationType()).append("了")
                    .append(questionInfo.getKnownTailEntity()).append("：");

            for (int i = 0; i < triples.size(); i++) {
                answer.append(triples.get(i).getHeadEntityName());
                if (i < triples.size() - 1) {
                    answer.append("、");
                }
            }
            answer.append("。");
        }

        return answer.toString();
    }

    /**
     * 生成询问尾实体的回答（如"秦始皇建立了什么？"）
     */
    private String generateTailEntityAnswer(QuestionInfo questionInfo, List<Triple> triples) {
        StringBuilder answer = new StringBuilder();

        if (triples.size() == 1) {
            Triple triple = triples.get(0);
            answer.append(questionInfo.getKnownHeadEntity())
                    .append(triple.getRelationType())
                    .append("了")
                    .append(triple.getTailEntityName())
                    .append("。");
        } else {
            answer.append(questionInfo.getKnownHeadEntity()).append("通过")
                    .append(questionInfo.getRelationType()).append("关系关联的实体有：");

            for (int i = 0; i < triples.size(); i++) {
                answer.append(triples.get(i).getTailEntityName());
                if (i < triples.size() - 1) {
                    answer.append("、");
                }
            }
            answer.append("。");
        }

        return answer.toString();
    }

    /**
     * 新增：无关系时的答案生成（展示实体的所有相关信息）
     */
    private String generateNoRelationAnswer(QuestionInfo questionInfo, List<Triple> triples) {
        // 取目标实体（最长的实体）
        String targetEntity = questionInfo.getEntities().stream()
                .max(Comparator.comparingInt(String::length))
                .orElse("未知实体");

        StringBuilder answer = new StringBuilder(targetEntity + "的相关信息如下：");

        // 遍历三元组，按“关系-实体”的格式展示
        for (Triple triple : triples) {
            String relation = triple.getRelationType() != null ? triple.getRelationType() : "关联";
            String otherEntity;
            // 判断目标实体是头实体还是尾实体，取另一端的实体
            if (targetEntity.equals(triple.getHeadEntityName())) {
                otherEntity = triple.getTailEntityName() != null ? triple.getTailEntityName() : "未知实体";
            } else {
                otherEntity = triple.getHeadEntityName() != null ? triple.getHeadEntityName() : "未知实体";
            }
            // 补充实体描述（若有）
            String entityDesc = "";
            if (targetEntity.equals(triple.getHeadEntityName()) && triple.getHeadEntityDesc() != null) {
                entityDesc = "（" + triple.getHeadEntityDesc() + "）";
            } else if (targetEntity.equals(triple.getTailEntityName()) && triple.getTailEntityDesc() != null) {
                entityDesc = "（" + triple.getTailEntityDesc() + "）";
            }
            // 拼接每一条信息
            answer.append("\n- ").append(relation).append("：").append(otherEntity).append(entityDesc);
        }

        return answer.toString();
    }

    /**
     * 当没有找到匹配结果时生成回答
     */
    private String generateNoAnswer(QuestionInfo questionInfo) {
        StringBuilder answer = new StringBuilder("抱歉，");

        if (!questionInfo.getEntities().isEmpty()) {
            answer.append("关于")
                    .append(questionInfo.getEntities().get(0));

            if (questionInfo.getRelationType() != null) {
                answer.append("的").append(questionInfo.getRelationType());
            }

            answer.append("信息暂未找到。");
        } else {
            answer.append("没有找到与问题相关的信息。");
        }

        return answer.toString();
    }


    /**
     * 核心方法：调用DeepSeek生成自然语言回答
     * @param userQuestion 用户原始问题
     * @param kgTriples 知识图谱查询到的三元组列表
     * @return 自然语言回答
     */
    public String generateNaturalAnswer(String userQuestion, List<Triple> kgTriples) {
        // 1. 处理“无事实”场景（兜底）
        if (kgTriples == null || kgTriples.isEmpty()) {
            return generateNoAnswer(userQuestion);
        }

        // 2. 构建DeepSeek的约束性Prompt（关键：避免LLM编造事实）
        String prompt = buildDeepSeekPrompt(userQuestion, kgTriples);

        // 3. 调用DeepSeek获取生成结果
        try {
            String llmResponse = llmClientUtil.callLlm(prompt);
            // 4. 简单清洗LLM返回结果（去除多余空行、格式符号）
            return cleanLlmResponse(llmResponse);
        } catch (Exception e) {
            // 5. LLM调用失败时的兜底回答（用原始三元组拼接）
            log.error("DeepSeek调用失败，使用兜底回答", e);
            return generateFallbackAnswer(kgTriples);
        }
    }

    // ---------------------- 辅助方法 ----------------------
    /**
     * 构建DeepSeek的Prompt：明确约束“基于事实回答”“适配历史领域”
     */
    private String buildDeepSeekPrompt(String userQuestion, List<Triple> kgTriples) {
        // 1. 拼接知识图谱中的事实（转为“主体-关系-客体”的易读格式）
        StringBuilder factsBuilder = new StringBuilder();
        for (int i = 0; i < kgTriples.size(); i++) {
            Triple triple = kgTriples.get(i);
            // 补充实体描述（若有，让LLM更了解背景）
            String subjectDesc = triple.getHeadEntityDesc() != null ?
                    "（" + triple.getHeadEntityDesc() + "）" : "";
            String objectDesc = triple.getTailEntityDesc() != null ?
                    "（" + triple.getTailEntityDesc() + "）" : "";

            factsBuilder.append(i + 1).append(". ")
                    .append(triple.getHeadEntityName()).append(subjectDesc)
                    .append(" - ")
                    .append(triple.getRelationType())
                    .append(" - ")
                    .append(triple.getTailEntityName()).append(objectDesc)
                    .append("\n");
        }

        // 2. Prompt模板（严格约束LLM行为）
        return String.format("""
                任务：你是专业的历史问答助手，需基于以下“精准事实”回答用户问题，严格遵守规则。
                
                一、用户问题：
                %s
                
                二、精准事实（仅基于这些事实回答，不添加未提及的信息）：
                %s
                
                三、回答规则：
                1. 语言风格：正式、流畅，符合历史领域表述（避免口语化、网络用语）；
                2. 逻辑结构：按“问题核心→事实展开”组织，若涉及多个事实，按“重要性/时间顺序”排列；
                3. 细节补充：若事实中包含实体描述（如“项羽（西楚霸王）”），需自然融入回答；
                4. 兜底处理：若事实无法完全回答问题，需明确说明“当前仅能提供以下信息：...”，不编造内容；
                5. 长度控制：回答长度50-200字（避免过短或冗长）。
                """, userQuestion, factsBuilder.toString());
    }

    /**
     * 清洗LLM返回结果（去除多余空行、符号）
     */
    private String cleanLlmResponse(String llmResponse) {
        if (llmResponse == null) return "";
        // 去除首尾空行、多余空格，处理LLM可能输出的格式符号（如“###”）
        return llmResponse.trim()
                .replaceAll("\\n+", "\n")  // 多空行转为单行
                .replaceAll("^###+", "")   // 去除开头的“###”标题符号
                .replaceAll("\\s{2,}", " "); // 多空格转为单个空格
    }

    /**
     * 无事实时的兜底回答
     */
    private String generateNoAnswer(String userQuestion) {
        return String.format("抱歉，暂未查询到与“%s”相关的历史信息，请尝试其他问题（如“项羽”“秦朝建立时间”）。", userQuestion);
    }

    /**
     * LLM调用失败时的兜底回答（用原始三元组拼接）
     */
    private String generateFallbackAnswer(List<Triple> kgTriples) {
        StringBuilder fallback = new StringBuilder("已查询到相关信息，但生成回答时出现异常，以下是关键事实：\n");
        for (Triple triple : kgTriples) {
            fallback.append("- ").append(triple.getHeadEntityName())
                    .append("的").append(triple.getRelationType())
                    .append("是").append(triple.getTailEntityName())
                    .append("\n");
        }
        return fallback.toString();
    }

    // 日志（需导入org.slf4j.Logger和LoggerFactory）
    private static final Logger log = (Logger) LoggerFactory.getLogger(AnswerGenerator.class);
}
